package com.ruoyi.framework.config;

import com.ruoyi.common.utils.Threads;
import com.ruoyi.framework.config.properties.ThreadPoolProperties;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 *
 * @author Lion Li
 **/
@Configuration
public class ThreadPoolConfig {

	@Autowired
	private ThreadPoolProperties threadPoolProperties;

	@Bean(name = "threadPoolTaskExecutor")
	@ConditionalOnProperty(prefix = "threadPoolTaskExecutor", name = "enabled", havingValue = "true")
	public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
		executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
		executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
		executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
		RejectedExecutionHandler handler;
		switch (threadPoolProperties.getRejectedExecutionHandler()) {
			case "CallerRunsPolicy":
				handler = new ThreadPoolExecutor.CallerRunsPolicy();
				break;
			case "DiscardOldestPolicy":
				handler = new ThreadPoolExecutor.DiscardOldestPolicy();
				break;
			case "DiscardPolicy":
				handler = new ThreadPoolExecutor.DiscardPolicy();
				break;
			default:
				handler = new ThreadPoolExecutor.AbortPolicy();
				break;
		}
		executor.setRejectedExecutionHandler(handler);
		return executor;
	}

	/**
	 * 执行周期性或定时任务
	 */
	@Bean(name = "scheduledExecutorService")
	protected ScheduledExecutorService scheduledExecutorService() {
		return new ScheduledThreadPoolExecutor(threadPoolProperties.getCorePoolSize(),
			new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
			@Override
			protected void afterExecute(Runnable r, Throwable t) {
				super.afterExecute(r, t);
				Threads.printException(r, t);
			}
		};
	}
}
